#define GETTEXT_PACKAGE "gsmon"
#include <glib/gi18n-lib.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <glib/gprintf.h>
#include "gsm-watcher.h"
#include "gsm-view.h"
#include "gsm-model.h"
#include "notifier.h"

#ifdef NDEBUG
	#define GSM_PATH_LOCALE "../share/locale"
#else
	#define GSM_PATH_LOCALE "./locale"
#endif

static GtkWidget *view;
static GsmModel *model;

static void
gsm_load_preferences (GsmModel *model, GsmView *view)
{
	gchar *path = g_build_filename (g_get_home_dir (), ".config", "gsmon",
			"preferences.conf", NULL);
	GKeyFile *kfile = g_key_file_new ();
	if (!g_key_file_load_from_file (kfile, path, G_KEY_FILE_NONE, NULL)) {
		g_free (path);
		g_key_file_free (kfile);
		return;
	}
	g_free (path);
	
	gint update_rate = g_key_file_get_integer (kfile, "General",
			"Update Rate", NULL);
	gsm_model_set_update_rate (model, update_rate);
	gsm_view_set_update_rate (view, update_rate);
	
	gchar *n_sound = g_key_file_get_string (kfile, "General",
			"Notification Sound", NULL);
	if (n_sound) {
		gsm_notifier_set_sound (n_sound);
		gsm_view_set_notification_sound (view, n_sound);
	}
}

static void
gsm_save_prefrences (GsmModel *model, GsmView *view)
{
	GKeyFile *kfile = g_key_file_new ();
	g_key_file_set_integer (kfile, "General", "Update Rate",
			gsm_model_get_update_rate (model));
	g_key_file_set_string (kfile, "General", "Notification Sound",
			gsm_notifier_get_sound ());
	
	gchar *path = g_build_filename (g_get_home_dir (), ".config", "gsmon",
			"preferences.conf", NULL);
	gsize length;
	gchar *data = g_key_file_to_data (kfile, &length, NULL);
	g_file_set_contents (path, data, length, NULL);
	g_free (data);
	g_free (path);
	
	g_key_file_free (kfile);
}

void
show_notification (GsmModel *model, const gchar *name, GsmWatcher *watcher,
		gpointer user_data)
{
	gchar *summary = g_strdup_printf (_("%s has connected"), name);
	gchar *body = g_strdup_printf (_("Server: %s\nServer name: %s\nPlayers: %d / %d"),
			watcher->address, watcher->name, watcher->num_players,
			watcher->max_players);
	
	gsm_notifier_show_message (summary, body);
	
	g_free (summary);
	g_free (body);
}

static void
watcher_error (GsmModel *model, GsmWatcher *watcher, GError *error,
		gpointer user_data)
{
	gsm_view_error (GSM_VIEW (view), watcher, error);
}

static gboolean
friend_name_change (GsmView *view, const gchar *name, GsmModel *model)
{
	return gsm_model_find_friend (model, name, NULL);
}

static void
preference_change (GsmView *view, const gchar *name, gpointer value, GsmModel *model)
{
	if (strcmp (name, "notification-sound") == 0)
		gsm_notifier_set_sound (value);
	else
		g_object_set (model, name, value, NULL);
}

static void
exiting (GtkObject *object, GsmModel *model)
{
	gsm_save_prefrences (model, GSM_VIEW (view));
	g_object_unref (model);
	gtk_main_quit ();
}

int
main (int argc, char **argv)
{
	gboolean showversion = FALSE;
	gboolean startminimized = FALSE;
	GError *error = NULL;
	
	GOptionEntry entries[] = {
		{"version", '\0', 0, G_OPTION_ARG_NONE, &showversion,
				N_("Show version number and exit"), NULL},
		{"minimized", 'm', 0, G_OPTION_ARG_NONE, &startminimized,
				N_("Start minimized in system tray"), NULL},
		{NULL}
	};
	
#ifdef ENABLE_NLS
	bindtextdomain (GETTEXT_PACKAGE, GSM_PATH_LOCALE);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);
#endif
	
	g_set_application_name (_("Game Servers Monitor"));
	
	if (!g_thread_supported ())
		g_thread_init (NULL);
	
	if (!gtk_init_with_args (&argc, &argv, "", entries, GETTEXT_PACKAGE, &error))
		g_error ("%s", error->message);
	
	if (showversion) {
		g_print ("Game Servers Monitor v0.0\n");
		return 0;
	}
	
	gchar *path = g_build_filename (g_get_home_dir (), ".config", "gsmon", NULL);
	g_mkdir_with_parents (path, 0750);
	g_free (path);
	
// model-view signals
	model = gsm_model_new ();
	
	view = gsm_view_new ();
	g_signal_connect (view, "destroy", G_CALLBACK (exiting), model);
	
	if (!startminimized)
		gsm_view_show (GSM_VIEW (view));
	
	gsm_load_preferences (model, GSM_VIEW (view));
	
	g_signal_connect_swapped (view, "server-add", G_CALLBACK (gsm_model_add_server), model);
	g_signal_connect_swapped (view, "server-remove", G_CALLBACK (gsm_model_remove_server), model);
	g_signal_connect_swapped (view, "address-change", G_CALLBACK (gsm_model_find_by_address), model);
	g_signal_connect (view, "preference-change", G_CALLBACK (preference_change), model);
	g_signal_connect_swapped (view, "friend-add", G_CALLBACK (gsm_model_add_friend), model);
	g_signal_connect_swapped (view, "friend-update", G_CALLBACK (gsm_model_update_friend), model);
	g_signal_connect_swapped (view, "friend-remove", G_CALLBACK (gsm_model_remove_friend), model);
	g_signal_connect (view, "friend-name-change", G_CALLBACK (friend_name_change), model);
	
	g_signal_connect_swapped (model, "watcher-add", G_CALLBACK (gsm_view_add_server), view);
	g_signal_connect_swapped (model, "watcher-update", G_CALLBACK (gsm_view_update_server), view);
	g_signal_connect_swapped (model, "watcher-remove", G_CALLBACK (gsm_view_remove_server), view);
	g_signal_connect (model, "watcher-error", G_CALLBACK (watcher_error), NULL);
	g_signal_connect_swapped (model, "friend-add", G_CALLBACK (gsm_view_add_friend), view);
	g_signal_connect_swapped (model, "friend-update", G_CALLBACK (gsm_view_update_friend), view);
	g_signal_connect_swapped (model, "friend-remove", G_CALLBACK (gsm_view_remove_friend), view);
	g_signal_connect_swapped (model, "friend-online", G_CALLBACK (show_notification), NULL);
	
	gsm_model_load_servers (model);
	gsm_model_load_friends (model);
	
	gtk_main ();
	
	return 0;
}
